package com.snail.study.nio;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @author tim
 * @since 2021-3-29
 */
public class ChannelTest {
    /**
     * 使用通道完成数据的复制
     */
    @Test
    public void test(){
        try (FileInputStream fis = new FileInputStream("1.jpg");
             FileOutputStream fos = new FileOutputStream("2.jpg");
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (inChannel.read(buffer) != -1){
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用直接缓冲区完成文件的复制(内存映射文件)
     */
    @Test
    public void test2(){
        try {
            FileChannel inChannel = FileChannel.open(Paths
                    .get("D:\\user\\Pictures\\Bili ScreenShot\\8533c0128da14a40936723bc70165852.png"),
                    StandardOpenOption.READ);
            FileChannel outChannel = FileChannel.open(Paths.get("3.png"),
                    StandardOpenOption.CREATE,
                    StandardOpenOption.WRITE,
                    StandardOpenOption.READ);
            //内存映射文件
            MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY,0,inChannel.size());
            MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE,0,inChannel.size());

            //直接对缓冲区进行数据的读写
            byte[] dst = new byte[inMappedBuf.limit()];
            inMappedBuf.get(dst);
            outMappedBuf.put(dst);
            inChannel.close();
            outChannel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通道之间的数据传输（直接缓冲区）
     */
    @Test
    public void test3() {

        try {
            FileChannel inChannel = FileChannel.open(Paths.get("3.png"),
                    StandardOpenOption.READ);
            FileChannel outChannel = FileChannel.open(Paths.get("3copy.png"),
                    StandardOpenOption.WRITE,
                    StandardOpenOption.READ,
                    StandardOpenOption.CREATE);
            inChannel.transferTo(0,inChannel.size(),outChannel);

            inChannel.close();
            outChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
